package snmp

import (
	"errors"
	"strconv"
	"strings"
)

const (
	IP_CODE = ".1.3.6.1.2.1.4.20.1.2" //walk
	IP_MAC  = ".1.3.6.1.2.1.2.2.1.6"  //walk

	MEM_TOTAL     = ".1.3.6.1.4.1.2021.4.5.0"  //get
	MEM_AVAILABLE = ".1.3.6.1.4.1.2021.4.6.0"  //get
	MEM_SHARED    = ".1.3.6.1.4.1.2021.4.13.0" //get
	MEM_BUFFER    = ".1.3.6.1.4.1.2021.4.14.0" //get
	MEM_CACHED    = ".1.3.6.1.4.1.2021.4.15.0" //get

	SYS_UPTIME = ".1.3.6.1.2.1.1.3.0" //get

	//自定义。
	CUSTOM_SET = ".1.3.6.1.4.1.100.1"
)

type SnmpConn struct {
	service *Snmp
	ip      string
}

func NewSnmpConn(ip string) *SnmpConn {
	return &SnmpConn{
		service: NewSnmp(ip),
		ip:      ip,
	}
}

//close
func (s *SnmpConn) Close() {
	s.service.Close()
}

//获取mac
func (s *SnmpConn) GetMac() (string, error) {
	res, err := s.service.Walk(IP_CODE)
	if err != nil {
		return "", errors.New("walk ip err: " + err.Error())
	}

	//提取ipAdEntIfIndex
	ipAdEntIfIndex := ""
	for k, v := range res {
		//判断IP是否存在
		if strings.Contains(k, s.ip) {
			ipAdEntIfIndex = v
			break
		}
	}
	if ipAdEntIfIndex == "" {
		return "", errors.New("ip not found")
	}

	//获取 IfPhysAddress 接口的物理地址
	res, err = s.service.Walk(IP_MAC + "." + ipAdEntIfIndex)
	if err != nil {
		return "", errors.New("walk mac err: " + err.Error())
	}

	return filterMac(res[IP_MAC+"."+ipAdEntIfIndex]), nil
}

//内存大小
func (s *SnmpConn) GetMemory() (string, error) {
	_, val, err := s.service.GetOne(MEM_TOTAL)
	if err != nil {
		return "", errors.New("get memory err: " + err.Error())
	}
	return val, nil
}

//内存使用率
func (s *SnmpConn) GetMemoryUsage() (string, error) {
	res, err := s.service.Get(
		[]string{MEM_TOTAL, MEM_AVAILABLE, MEM_SHARED, MEM_BUFFER, MEM_CACHED},
	)
	if err != nil {
		return "", errors.New("get memory usage err: " + err.Error())
	}

	//数据转换成int
	var total, available, shared, buffer, cached int64
	total, _ = strconv.ParseInt(res[MEM_TOTAL], 10, 64)
	available, _ = strconv.ParseInt(res[MEM_AVAILABLE], 10, 64)
	shared, _ = strconv.ParseInt(res[MEM_SHARED], 10, 64)
	buffer, _ = strconv.ParseInt(res[MEM_BUFFER], 10, 64)
	cached, _ = strconv.ParseInt(res[MEM_CACHED], 10, 64)

	//当 memShared + memBuffer + memCached > memTotal 时，memUsage = (memTotal - memAvailable - memBuffer - memCached + memShared )/memTotal * 100
	if shared+buffer+cached > total {
		return calcMemUsage(total-available-buffer-cached+shared, total), nil
	}

	//当 memShared + memBuffer + memCached <= memTotal 时，memUsage = (memTotal - memAvailable - memBuffer - memCached )/memTotal * 100
	return calcMemUsage(total-available-buffer-cached, total), nil
}

//获取系统运行时间
func (s *SnmpConn) GetSysUpTime() (string, error) {
	_, res, err := s.service.GetOne(SYS_UPTIME)
	if err != nil {
		return "", errors.New("get sys up time err: " + err.Error())
	}
	return res, nil
}

//set 重启设备
func (s *SnmpConn) SetReboot() (string, error) {
	_, res, err := s.service.Set(CUSTOM_SET, "reboot")
	if err != nil {
		return "", errors.New("set reboot err: " + err.Error())
	}
	return res, nil
}
